home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48_1 / spline < prev    next >
Text File  |  1995-03-31  |  13KB  |  490 lines

  1. Article 4947 of comp.sys.handhelds:
  2. Path: en.ecn.purdue.edu!noose.ecn.purdue.edu!samsung!usc!sdd.hp.com!elroy.jpl.nasa.gov!ames!haven!umbc3!math13.math.umbc.edu!rouben
  3. From: rouben@math13.math.umbc.edu (Rouben Rostamian)
  4. Newsgroups: comp.sys.handhelds
  5. Subject: SPLINE v2.0 for HP48 (repost)
  6. Message-ID: <5366@umbc3.UMBC.EDU>
  7. Date: 11 Mar 91 15:16:33 GMT
  8. Sender: newspost@umbc3.UMBC.EDU
  9. Reply-To: rouben@math13.math.umbc.edu
  10. Organization: Mathematics Department University of Maryland, Baltimore County
  11. Lines: 475
  12.  
  13. I had trouble with posting this porgram earlier today.  This is a repost.
  14. I apologize if you received duplicate copies.
  15. --
  16. Rouben Rostamian                          Telephone: (301) 455-2458
  17. Department of Mathematics and Statistics  e-mail:
  18. University of Maryland Baltimore County   bitnet: rostamian@umbc.bitnet
  19. Baltimore, MD 21228,  U.S.A.              internet: rouben@math9.math.umbc.edu
  20.  
  21. ---------------------------------------------------------------------------
  22. This is version 2.0 of SPLINE.  SPLINE generates a piecewise cubic and twice
  23. continuously differentiable interpolation y(x) of a set of points (x_i,y_i),
  24. i=1,2,...,n.  It is assumed throughout that x_1 < x_2 < ... < x_n.
  25.  
  26. SPLINE's default action is to generate a _natural_ cubic spline, i.e., the
  27. second derivative y'' vanishes at the end points x_1 and x_n.  The default
  28. action of SPLINE may be modified by specifying optional switches which are
  29. described later.
  30.  
  31. ------- INPUT --------------------------------------------------------
  32. SPLINE reads its input from the stack.  The n coordinate points may be
  33. specified in two different formats:
  34.  
  35. THE COORDINATE-PAIRS INPUT FORMAT:
  36. n+1: (x_1,y_1)
  37. n:   (x_2,y_2)
  38.      ...
  39. 2:   (x_n,y_n)
  40. 1:           n
  41.  
  42. THE ARRAY INPUT FORMAT:
  43. 2:   [ y_1 y_2 ... y_n ]
  44. 1:           [ x_1 x_n ]
  45.  
  46. In the ARRAY input format the interval [x_1 x_n] is automatically divided
  47. into n equally spaced nodes.  The COORDINATE-PAIRS format is useful if
  48. the nodes are not equally spaced.
  49.  
  50. ----------- OUTPUT ----------------------------------------------------
  51. The output of SPLINE is a *program* which can be used as a user-defined
  52. function.  The program, which is placed on level 1 of the stack, has the 
  53. following general format:
  54.  
  55. 1: << -> X 
  56.       << 
  57.           Description of the spline curve here
  58.       >>
  59.    >>
  60.  
  61. This program may be stored in a variable, say TRY, and may be
  62. evaluated as "TRY(X)" (algebraic mode) or as "X TRY" (RPN mode.)
  63. TRY(X) may be plotted with the usual plotting commands.
  64.  
  65. -------- OPTIONAL SWITCHES ---------------------------------------------
  66. o  SPLINE by default imposes the natural boundary conditions
  67. y''(x_1) = y''(x_n) = 0.  It is possible to specify instead the first
  68. derivatives a := y'(x_1) and b := y'(x_n) as boundary conditions.
  69. For this, enter the data in one of the two formats described
  70. before, then push the list { a b } into the level 1 of stack.
  71.  
  72. o  SPLINE can also return the first derivative y'(x) and the second
  73. derivative y''(x) of the cubic spline interpolant.  To get these, enter 
  74. data as before, optionally enter the list { a b } from the
  75. previous paragraph, then push the characters 'D1' into level 1
  76. to compute y'(x), or 'D2' to compute y''(x).
  77.  
  78. ---------- EXAMPLES --------------------------------------------------
  79. Example 1:
  80.     5:  (0,0)
  81.     4:  (1,1)
  82.     3:  (2,4)
  83.     2: (4,16)
  84.     1:     4
  85.  
  86. SPLINE returns the program:
  87.  
  88. 1: << -> X
  89.   <<
  90.     CASE 'X' 2 >=
  91.       THEN '2.60869565217*(4-X)^3/2/6+6.86956521739*(X-2)+2.26086956522'
  92.       END 'X' 1 >=
  93.       THEN '(2.34782608696*(2-X)^3+2.60869565217*(X-1)^3)/6
  94.                      +2.95652173913*(X-1)+.608695652173'
  95.       END  '2.34782608696X^3/6+.608695652173*X'
  96.     END EVAL
  97.   >>
  98. >>
  99.  
  100. Example 2a:
  101.     2: [ 0 1 0 1 0 1 0 ]
  102.     1:           [ 0 9 ]
  103.  
  104. The second derivative is zero at the end points.
  105.  
  106. Example 2b:
  107.     3: [ 0 1 0 1 0 1 0 ]
  108.     2:           [ 0 9 ]
  109.     1:           { 0 0 }
  110.  
  111. The first derivative is  zero at the ends.   Replacing { 0 0 } by { 1 -1 }
  112. makes the first derivative equal 1 and -1 at the ends.
  113.  
  114. Example 2c:
  115.     4: [ 0 1 0 1 0 1 0 ]
  116.     3:           [ 0 9 ]
  117.     2:           { 0 0 }
  118.     1:              'D1'
  119.  
  120. Computes the first derivative y'(x) of the spline y(x) of example 2b.
  121. Replacing 'D1' with 'D2' will computes the second derivative.   It is
  122. instructive to save y(x), y'(x), and y''(x) into variables Y0, Y1, and Y2,
  123. and PLOT { 'Y2(X)' 'Y1(X)' Y0(X)' } with XRANGE set to 0,9 and AUTO.
  124.  
  125. -------- REFERENCE -----------------------------------------------------
  126. Stoer and Bulirsch, Numerical Analysis
  127.  
  128. -------- REMARKS -------------------------------------------------------
  129. SPLINE does not use, change, create or modify any global variables.
  130. It does not modify parts of the stack it does not own and does not
  131. alter any system flags, although the calculator has to be in the
  132. symbolic mode for SPLINE to operate.   It clears _user_ flags 6,7,8,9.
  133.  
  134. -------- NOTES ---------------------------------------------------------
  135. SPLINE V2.0 is completely different from an earlier version (no version
  136. number) that I posted to comp.sys.handhelds a few weeks ago.  This new
  137. version generates code which executes about 4 times faster than the
  138. previous version.  It also has many additional features.  I will not
  139. describe the differences here because because I consider the previous
  140. version obsolete.
  141.  
  142. -------- PROGRAM OBJECT CHECKSUMS --------------------------------------
  143. Checksum: #3B69h
  144. Bytes:      2212
  145.  
  146. -------- COMMENTED PROGRAM (Uncommented program follows) -------------- 
  147.  
  148. %%HP: T(3)A(D)F(.);
  149. \<<
  150. @ Display version while working
  151. "     SPLINE V2.0
  152.   " 1 DISP
  153.  
  154.   6 CF 7 CF 8 CF 9 CF        @ Prepare flags 6-9
  155.  
  156.   IF DUP TYPE 6 SAME        @ Check if 'D1' or 'D2' are specified
  157.   THEN
  158.     CASE DUP 'D1' SAME
  159.       THEN 6 SF            @ Set flag 6 if 'D1' specified
  160.       END DUP 'D2' SAME
  161.       THEN 7 SF            @ Set flag 7 if 'D2' specified
  162.       END DUP \->STR ": Unknown flag" + DOERR        
  163.     END
  164.     DROP            @ Drop 'D1' or 'D2' from stack
  165.   END
  166.  
  167.   IF DUP TYPE 5 \=/        @ See if the end-derivatives are specified
  168.   THEN { 0 0 }            @ If not, insert {0 0} (as a place holder)
  169.   ELSE 8 SF            @ If yes, then set flag 8
  170.   END
  171.   
  172.   IF OVER TYPE 0 SAME        @ If we have a number n in level 2 then we 
  173.   THEN OVER 2 + ROLLD        @ expect n pairs of coordinates above it
  174.   ELSE SWAP ROT            @ Otherwise we expect two arrays in levels 2
  175.   END                @ and 3.  In either case, we move the { s1 s2 }
  176.                 @ list form level 1 to the top of the stack.
  177.  
  178.   IF DUP TYPE 0 \=/        @ If we don't have a number in level 1
  179.   THEN 9 SF            @ Then the coordinates are given as arrays
  180.   DUP SIZE EVAL            @ Determine the size of array
  181.   END
  182.  
  183.                 @ Set up the local variables
  184.      DUP 1 - { } { } 0  0   0  0 0 0 0 0   0    0   0   0
  185.   \->   n  k  x   y  h \Gl \Gm s d m a b \Gl0 \Gmn s11 s1n
  186.  
  187.   @ Begin the main program
  188.   \<<
  189.  
  190.     IF 9 FC?C
  191.     THEN 1 n            @ Flag 9 is clear so data is in coord. pairs
  192.       FOR j            @ Convert coordinate pairs into lists x and y
  193.           C\->R 'y' STO+ 'x' STO+
  194.       NEXT
  195.     ELSE
  196.       OBJ\-> EVAL \->LIST 'y' STO    @ Store array of y_i into the list y
  197.       OBJ\-> DROP OVER - k /        @ Compute the mesh size
  198.       0 k
  199.       FOR j
  200.         DUP j * 3 PICK + 3 ROLLD    @ Generate the x mesh
  201.       NEXT
  202.       DROP2 n \->LIST 'x' STO        @ Store the x values into the list x
  203.     END
  204.  
  205.     EVAL 's1n' STO 's11' STO        @ Read the end-derivative values
  206.  
  207.     x EVAL                 @ Compute the list of
  208.     1 k                    @ interval lengths h_j = x_{j+1} - x_j
  209.     FOR j OVER - n ROLLD
  210.     NEXT
  211.     DROP
  212.     k \->LIST 'h' STO
  213.  
  214.     1 k                    @ Compute the list of slopes s_j
  215.     FOR j                @ s_j = ( y_{j+1} - y_j ) / h_j
  216.       y j GETI 3 ROLLD GET - NEG h j GET /
  217.     NEXT
  218.     k \->LIST 's' STO
  219.  
  220.     @ Compute the elements d_j of the list d:
  221.     IF 8 FS?
  222.     THEN                @ End-derivatives are specified
  223.       1 '\Gl0' STO
  224.       1 '\Gmn' STO
  225.       s 1 GET s11 - h 1 GET / 6 *
  226.     ELSE 0
  227.     END
  228.  
  229.     @ Still computing d:
  230.     1 n 2 -
  231.     FOR j
  232.       s j GETI 3 ROLLD GET - NEG h j GETI 3 ROLLD GET + / 6 *
  233.     NEXT
  234.  
  235.     @ End of computation of d:
  236.     IF 8 FS?C
  237.     THEN
  238.       s1n s k GET - h k GET / 6 *
  239.     ELSE 0
  240.     END
  241.     n \->LIST 'd' STO
  242.  
  243.  
  244.     @ Compute lambda_j:
  245.     h OBJ\-> 1 - 1 SWAP
  246.     FOR j
  247.       DUP 3 PICK + / k ROLLD
  248.     NEXT
  249.     DROP
  250.     n 2 - \->LIST '\Gl' STO
  251.  
  252.     @ Compute gamma_j:
  253.     \Gl OBJ\-> 1 SWAP
  254.     FOR j
  255.       NEG 1 +
  256.       n 2 - ROLL
  257.     NEXT
  258.     n 2 - \->LIST '\Gm' STO
  259.  
  260.     @ Compute the moments m_j:
  261.     n IDN 2 *
  262.     2 k
  263.     FOR j
  264.       j DUP 1 - 2 \->LIST
  265.       \Gm j 1 - GET
  266.       PUT
  267.       j DUP 1 + 2 \->LIST
  268.       \Gl j 1 - GET
  269.       PUT
  270.     NEXT
  271.     2 \Gl0 PUT
  272.     n SQ 1 - \Gmn PUT
  273.     INV
  274.     d OBJ\-> \->ARRY *
  275.     'm' STO
  276.  
  277.     @ Compute a_j:
  278.     1 k
  279.     FOR j
  280.       m j GETI 3 ROLLD GET - h j GET * 6 / s j GET +
  281.     NEXT
  282.     k \->LIST 'a' STO
  283.  
  284.     @ Compute b_j:
  285.     1 k
  286.     FOR j
  287.       y j GET m j GET h j GET SQ * 6 / -
  288.     NEXT
  289.     k \->LIST 'b' STO
  290.  
  291.     @ Now we compute the individual arcs of the spline:
  292.     CASE 6 FS?C
  293.       THEN                @ Will compute y'(x)
  294.         1 k
  295.         FOR j
  296.           m j 1 + GET 'X' x j GET - SQ *
  297.       m j GET x j 1 + GET 'X' - SQ * -
  298.       h j GET / 2 / a j GET +
  299.         NEXT
  300.       END 7 FS?C
  301.       THEN                @ Will compute y''(x)
  302.       1 k
  303.       FOR j
  304.         m j GET x j 1 + GET 'X' - *
  305.     m j 1 + GET 'X' x j GET - * +
  306.     h j GET / NEXT
  307.       END
  308.       1 k
  309.       FOR j                @ Will compute y(x)
  310.       m j GET x j 1 + GET 'X' - 3 ^ *
  311.       m j 1 + GET 'X' x j GET - 3 ^ * +
  312.       h j GET / 6 /
  313.       a j GET 'X' x j GET - * +
  314.       b j GET +
  315.       NEXT
  316.     END
  317.  
  318.     @ Create the output program:
  319.     "\<<\-> X\<<CASE " n ROLLD
  320.     k 2
  321.     FOR j
  322.       'X' " " + x j GET + " \>= THEN " + SWAP + " END " +
  323.       j ROLLD
  324.       -1
  325.     STEP
  326.    " END EVAL\>>\>>"
  327.  
  328.    @ Concatenate all parts:
  329.    1 n
  330.    FOR j +
  331.    NEXT
  332.    OBJ\->
  333.   \>>
  334. \>>
  335.  
  336. ----------- UNCOMMENTED PROGRAM -------------------------------------------
  337.  
  338. %%HP: T(3)A(D)F(.);
  339. \<<
  340. "     SPLINE V2.0
  341.   "
  342. 1 DISP 6 CF 7 CF 8
  343. CF 9 CF
  344.   IF DUP TYPE 6
  345. SAME
  346.   THEN
  347.     CASE DUP 'D1'
  348. SAME
  349.       THEN 6 SF
  350.       END DUP 'D2'
  351. SAME
  352.       THEN 7 SF
  353.       END DUP \->STR
  354. ": Unknown flag" +
  355. DOERR
  356.     END DROP
  357.   END
  358.   IF DUP TYPE 5 \=/
  359.   THEN { 0 0 }
  360.   ELSE 8 SF
  361.   END
  362.   IF OVER TYPE 0
  363. SAME
  364.   THEN OVER 2 +
  365. ROLLD
  366.   ELSE SWAP ROT
  367.   END
  368.   IF DUP TYPE 0 \=/
  369.   THEN 9 SF DUP
  370. SIZE EVAL
  371.   END DUP 1 - { } {
  372. } 0 0 0 0 0 0 0 0 0
  373. 0 0 0 \-> n k x y h \Gl
  374. \Gm s d m a b \Gl0 \Gmn
  375. s11 s1n
  376.   \<<
  377.     IF 9 FC?C
  378.     THEN 1 n
  379.       FOR j C\->R 'y'
  380. STO+ 'x' STO+
  381.       NEXT
  382.     ELSE OBJ\-> EVAL
  383. \->LIST 'y' STO OBJ\->
  384. DROP OVER - k / 0 k
  385.       FOR j DUP j *
  386. 3 PICK + 3 ROLLD
  387.       NEXT DROP2 n
  388. \->LIST 'x' STO
  389.     END EVAL 's1n'
  390. STO 's11' STO x
  391. EVAL 1 k
  392.     FOR j OVER - n
  393. ROLLD
  394.     NEXT DROP k
  395. \->LIST 'h' STO 1 k
  396.     FOR j y j GETI
  397. 3 ROLLD GET - NEG h
  398. j GET /
  399.     NEXT k \->LIST
  400. 's' STO
  401.     IF 8 FS?
  402.     THEN 1 '\Gl0' STO
  403. 1 '\Gmn' STO s 1 GET
  404. s11 - h 1 GET / 6 *
  405.     ELSE 0
  406.     END 1 n 2 -
  407.     FOR j s j GETI
  408. 3 ROLLD GET - NEG h
  409. j GETI 3 ROLLD GET
  410. + / 6 *
  411.     NEXT
  412.     IF 8 FS?C
  413.     THEN s1n s k
  414. GET - h k GET / 6 *
  415.     ELSE 0
  416.     END n \->LIST 'd'
  417. STO h OBJ\-> 1 - 1
  418. SWAP
  419.     FOR j DUP 3
  420. PICK + / k ROLLD
  421.     NEXT DROP n 2 -
  422. \->LIST '\Gl' STO \Gl
  423. OBJ\-> 1 SWAP
  424.     FOR j NEG 1 + n
  425. 2 - ROLL
  426.     NEXT n 2 -
  427. \->LIST '\Gm' STO n IDN
  428. 2 * 2 k
  429.     FOR j j DUP 1 -
  430. 2 \->LIST \Gm j 1 - GET
  431. PUT j DUP 1 + 2
  432. \->LIST \Gl j 1 - GET
  433. PUT
  434.     NEXT 2 \Gl0 PUT n
  435. SQ 1 - \Gmn PUT INV d
  436. OBJ\-> \->ARRY * 'm'
  437. STO 1 k
  438.     FOR j m j GETI
  439. 3 ROLLD GET - h j
  440. GET * 6 / s j GET +
  441.     NEXT k \->LIST
  442. 'a' STO 1 k
  443.     FOR j y j GET m
  444. j GET h j GET SQ *
  445. 6 / -
  446.     NEXT k \->LIST
  447. 'b' STO
  448.     CASE 6 FS?C
  449.       THEN 1 k
  450.         FOR j m j 1
  451. + GET 'X' x j GET -
  452. SQ * m j GET x j 1
  453. + GET 'X' - SQ * -
  454. h j GET / 2 / a j
  455. GET +
  456.         NEXT
  457.       END 7 FS?C
  458.       THEN 1 k
  459.         FOR j m j
  460. GET x j 1 + GET 'X'
  461. - * m j 1 + GET 'X'
  462. x j GET - * + h j
  463. GET /
  464.         NEXT
  465.       END 1 k
  466.       FOR j m j GET
  467. x j 1 + GET 'X' - 3
  468. ^ * m j 1 + GET 'X'
  469. x j GET - 3 ^ * + h
  470. j GET / 6 / a j GET
  471. 'X' x j GET - * + b
  472. j GET +
  473.       NEXT
  474.     END
  475. "\<<\-> X\<<CASE " n
  476. ROLLD k 2
  477.     FOR j 'X' " " +
  478. x j GET +
  479. " \>= THEN " + SWAP +
  480. " END " + j ROLLD
  481. -1
  482.     STEP
  483. " END EVAL\>>\>>" 1 n
  484.     FOR j +
  485.     NEXT OBJ\->
  486.   \>>
  487. \>>
  488.  
  489.  
  490.